package net.sf.midollo.task;

public class TaskPool implements Runnable {

	private Object lockAddTask = new Object();
	private Object lockRemoveTask = new Object();
	private Runnable task = null;
	private ThreadGroup threadGroup;
	private final Thread[] threads;

	public TaskPool(int num) {
		this.threadGroup = new ThreadGroup(this.getClass().getName());
		this.threads = new Thread[num];
		for (int i = 0; i < this.threads.length; ++i) {
			TaskPoolEntry entry = new TaskPoolEntry(this);
			this.threads[i] = new Thread(this.threadGroup, entry);
		}
	}

	public void run() {
		for (int i = 0; i < this.threads.length; ++i)
			this.threads[i].start();
		try {
			for (int i = 0; i < this.threads.length; ++i)
				this.threads[i].join();
		} catch (InterruptedException e) {
		}
	}

	public void addTask(Runnable task) throws InterruptedException {
		synchronized (this.lockRemoveTask) {
			if (this.task != null)
				this.lockRemoveTask.wait();
		}
		synchronized (this.lockAddTask) {
			this.task = task;
			if (this.task != null) {
				this.lockAddTask.notifyAll();
			}
		}
	}

	public Runnable nextTask() throws InterruptedException {
		Runnable task = null;
		synchronized (this.lockAddTask) {
			this.lockAddTask.wait();
			task = this.task;
		}
		synchronized (this.lockRemoveTask) {
			this.task = null;
			this.lockRemoveTask.notifyAll();
		}
		return task;
	}
}
